import math
import os
import re
import sys
# PyQt5中使用的基本控件都在PyQt5.QtWidgets模块中
import threading
import time

import chardet
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QTableWidgetItem, QMessageBox, QMenu
# 导入designer工具生成的login模块
from numpy.random import randint
from mainui import Ui_MainWindow
import pandas as pd
import jieba

jieba.set_dictionary('dict/dict.txt')
jieba.initialize()  # 手动初始化（可选）
index_transform = []
data = ["江苏南京市建邺区友谊街38号9幢一单元103室", "江苏南京市建邺区友谊街38号4幢三单元1411室"]
myumap = {
    '市辖区': '南京市',
    '玄武区': '南京市',
    '鼓楼区': '南京市',
    '秦淮区': '南京市',
    '建邺区': '南京市',
    '浦口区': '南京市',
    '栖霞区': '南京市',
    '雨花台区': '南京市',
    '江宁区': '南京市',
    '六合区': '南京市',
    '溧水区': '南京市',
    '高新开发区': '南京市',
    '经济技术开发区': '南京市',

}


def transform(location_strs, umap=myumap, index=[], cut=True, lookahead=8):
    from word.transformer import CPCATransformer
    index_transform = index
    # loc这里的作用纯粹是为了让输出结果更好看一些
    word = CPCATransformer(umap)
    # ret = word.transform(location_strs, index, cut, lookahead).loc[:, ('省', '市', '区', '地址')]
    ret = word.transform(location_strs, index, cut, lookahead)
    return ret


class MyMainForm(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainForm, self).__init__(parent)
        self.datadf = None
        self.setupUi(self)
        # 获取运行路径
        self.lineEdit.setText(os.getcwd())
        # 开始
        self.pushButton.clicked.connect(lambda: MyThread(self.start))
        # 选择文件
        self.pushButton_open.clicked.connect(self.open)
        # 选择输出文件夹
        self.pushButton_open_put.clicked.connect(self.put)
        # 右键菜单
        self.tableWidget.customContextMenuRequested.connect(self.generateMenu)

    # 右键菜单
    def generateMenu(self, pos):
        # rint( pos)
        row_num = -1
        for i in self.tableWidget.selectionModel().selection().indexes():
            row_num = i.row()

        if row_num >= 0:
            menu = QMenu()
            item1 = menu.addAction(u"导出")
            item2 = menu.addAction(u"清空")
            action = menu.exec_(self.tableWidget.mapToGlobal(pos))
            if action == item1:

                if self.datadf is not None:
                    if self.radioButton_rand.isChecked():
                        name = str(randint(100000, 999999999))
                    elif self.radioButton_date.isChecked():
                        name = str(int(time.time())) + str(randint(100000, 999999999))
                    else:
                        name = str(int(time.time()))
                    self.datadf.to_excel(self.lineEdit.text() + "/" + name + ".xlsx", index=False)

                    QMessageBox.information(self, "提示", "导出成功。导出文件名为：" + name + ".xlsx", QMessageBox.Yes)
                else:
                    QMessageBox.information(self, "提示", "表格中没有任何数据", QMessageBox.Yes)
            if action == item2:
                self.datadf = None
                self.tableWidget.setRowCount(0)

            else:

                return

    # 选择文件
    def open(self):
        path = QFileDialog.getOpenFileName(self, "请选择文件路径", "",
                                           "XlSX Files(*.xlsx);;CSV Files(*.csv);;TXT Files(*.txt);;全部文件(*)")
        if path:
            self.label_xz.setText("已选择")
            self.lineEdit_wd_adderss.setText(path[0])

    # 选择输出文件夹
    def put(self):
        path = QFileDialog.getExistingDirectory(self)
        if path:
            self.lineEdit.setText(path)

    def start(self):
        self.label_system.setText("提示:正在运行中...请耐心等待")
        if self.radioButton_gn_auto.isChecked():
            # 自动判断
            if self.lineEdit_wd_adderss.text():
                # 文档
                self.gn_wd()
                pass
            elif self.textEdit.toPlainText():
                # 文本
                self.gn_wb()
                pass
            else:
                self.label_system.setText("提示:请先导入文档地址，或者输入要转换的文本地址")

            if self.lineEdit_wd_adderss.text() and self.textEdit.toPlainText():
                # 文本
                self.gn_wb()
                pass
        if self.radioButton_gn_wb.isChecked():
            # 文本
            if self.textEdit.toPlainText():
                # 文本
                self.gn_wb()

            else:
                self.label_system.setText("提示:请先输入要转换的文本地址")

        if self.radioButton_gn_wd.isChecked():
            # 文档
            if self.lineEdit_wd_adderss.text():
                # 文档
                self.gn_wd()
                pass
            else:
                self.label_system.setText("提示:请先导入文档地址")

        if self.label_system.text() == "提示:正在运行中...请耐心等待":
            self.label_system.setText("运行完成，鼠标右键表格可以导出文档")

    # 文档功能
    def gn_wd(self):
        dataFile = None
        path = self.lineEdit_wd_adderss.text()

        matchObj = re.findall(r"(csv|xlsx|txt)$", path)
        self.pushButton.setEnabled(False)
        if matchObj:
            try:
                if matchObj[0] == "csv":
                    # 检查编码
                    encod = self.comboBox.currentText()
                    if encod == "auto(上面两个编码无法正常读取文件请用这个)":
                        encod = self.get_encoding(path)
                    # csv

                    if self.radioButton_table_head_yes.isChecked():
                        dataFile = pd.read_csv(path, encoding=encod)

                        if dataFile is not None:
                            headtitle = self.lineEdit_table_title.text()
                            if headtitle:
                                if len(dataFile.index) > 1000:

                                    a = math.ceil(len(dataFile.index) / 1000)
                                    i = 0
                                    for item in range(a):
                                        i += 1
                                        words = transform(dataFile[1000 * item:1000 * i][headtitle])
                                        self.tableAdd(words)


                                else:

                                    words = transform(dataFile[headtitle])
                                    self.tableAdd(words)
                            else:
                                self.label_system.setText("提示:请输入表头标题（需要解析的地址列标题）")

                        else:
                            time.sleep(0.1)
                            self.label_system.setText("提示:处理文件失败，请检查设置是否正确")


                    else:

                        dataFile = pd.read_csv(path, encoding=encod, header=None)

                        if dataFile is not None:
                            if len(dataFile.index) > 1000:

                                a = math.ceil(len(dataFile.index) / 1000)
                                i = 0
                                for item in range(a):
                                    i += 1
                                    words = transform(dataFile[1000 * item:1000 * i][0])
                                    self.tableAdd(words)


                            else:
                                words = transform(dataFile[0])
                                self.tableAdd(words)

                        else:
                            time.sleep(0.1)
                            self.label_system.setText("提示:处理文件失败，请检查设置是否正确")

                    pass
                elif matchObj[0] == "xlsx":
                    # xlsx

                    if self.radioButton_table_head_yes.isChecked():
                        dataFile = pd.read_excel(path)
                        if dataFile is not None:
                            headtitle = self.lineEdit_table_title.text()
                            if headtitle:
                                if len(dataFile.index) > 1000:

                                    a = math.ceil(len(dataFile.index) / 1000)
                                    i = 0
                                    for item in range(a):
                                        i += 1
                                        words = transform(dataFile[1000 * item:1000 * i][headtitle])
                                        self.tableAdd(words)


                                else:

                                    words = transform(dataFile[headtitle])
                                    self.tableAdd(words)
                            else:
                                self.label_system.setText("提示:请输入表头标题（需要解析的地址列标题）")



                        else:
                            self.label_system.setText("提示:处理文件失败，请检查设置是否正确")

                    else:
                        dataFile = pd.read_excel(path, header=None)

                        if dataFile is not None:
                            if len(dataFile.index) > 1000:

                                a = math.ceil(len(dataFile.index) / 1000)
                                i = 0
                                for item in range(a):
                                    i += 1
                                    words = transform(dataFile[1000 * item:1000 * i][0])
                                    self.tableAdd(words)


                            else:
                                words = transform(dataFile[0])
                                self.tableAdd(words)

                        else:
                            time.sleep(0.1)
                            self.label_system.setText("提示:处理文件失败，请检查设置是否正确")


                elif matchObj[0] == "txt":
                    # txt
                    encod = self.comboBox.currentText()
                    if encod == "auto(上面两个编码无法正常读取文件请用这个)":
                        encod = self.get_encoding(path)
                    file = open(path, encoding=encod)
                    text = file.read()
                    file.close()
                    # 用换行符分割文本
                    dataFile = text.splitlines()
                    words = transform(dataFile)
                    self.tableAdd(words)
            except UnicodeError:
                time.sleep(0.1)
                self.label_system.setText("提示:文件编码错误，请更换编码或者使用auto模式")

            except KeyError:
                time.sleep(0.1)
                self.label_system.setText("提示:表头标题设置错误，表中没有找到该表头标题(或文件中有空白行)")

        else:
            time.sleep(0.1)
            self.label_system.setText("提示:您导入的文件不符合规则(csv|xlsx|txt)")

        self.pushButton.setEnabled(True)

    def thread_it(self, func, *args):
        '''将函数打包进线程'''
        # 创建
        t = threading.Thread(target=func, args=args)
        # 守护 !!!
        t.setDaemon(True)
        # 启动
        t.start()
        # 阻塞--卡死界面！
        # t.join()

    # 获取文件编码类型
    def get_encoding(self, file):
        # 二进制方式读取，获取字节数据，检测类型

        with open(file, 'rb') as f:
            data = f.read()
            return chardet.detect(data)['encoding']

    # 文本功能
    def gn_wb(self):
        data = self.textEdit.toPlainText().splitlines()

        words = transform(data)
        self.tableAdd(words)

    def tableAdd(self, words):
        for index, row in words.iterrows():
            intRow = self.tableWidget.rowCount()

            self.tableWidget.insertRow(int(intRow))

            self.tableWidget.setItem(intRow, 0, QTableWidgetItem(row['地址名称']))
            self.tableWidget.setItem(intRow, 1, QTableWidgetItem(row['行政区划中文']))
            self.tableWidget.setItem(intRow, 2, QTableWidgetItem(row['街路巷中文']))
            self.tableWidget.setItem(intRow, 3, QTableWidgetItem(row['门牌号']))
            self.tableWidget.setItem(intRow, 4, QTableWidgetItem(row['门牌后缀中文']))
            self.tableWidget.setItem(intRow, 5, QTableWidgetItem(row['幢楼号']))
            self.tableWidget.setItem(intRow, 6, QTableWidgetItem(row['幢楼后缀中文']))
            self.tableWidget.setItem(intRow, 7, QTableWidgetItem(row['单元号']))
            self.tableWidget.setItem(intRow, 8, QTableWidgetItem(row['室号']))
            self.tableWidget.setItem(intRow, 9, QTableWidgetItem(row['室号后缀中文']))

            self.tableWidget.update()
        if self.datadf is not None:
            self.datadf = pd.concat([self.datadf, words])

        else:
            self.datadf = words


class MyThread(threading.Thread):
    def __init__(self, func, *args):
        super().__init__()

        self.func = func
        self.args = args

        self.setDaemon(True)
        self.start()  # 在这里开始

    def run(self):
        self.func(*self.args)


if __name__ == "__main__":
    # 初始化
    word = transform(data)
    # Record()
    # 固定的，PyQt5程序都需要QApplication对象。sys.argv是命令行参数列表，确保程序可以双击运行
    app = QApplication(sys.argv)
    # 初始化
    myWin = MyMainForm()
    # 将窗口控件显示在屏幕上
    myWin.show()
    # 程序运行，sys.exit方法确保程序完整退出。
    sys.exit(app.exec_())
